#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>

#define PI 3.141592654

typedef struct {
   float x;
   float y;
}Punto;

void inicializa(void);
void dibuja(void);
void tecladoEspecial(int key, int cx, int cy);
void teclado(unsigned char key, int cx, int cy);
void dibujaEstrella(float, float);
void dibujaFlecha(void);
void drawAxes(void);
void pglTranslatef(float, float);
void pglRotatef(float);
void pglScalef(float, float);

Punto u;
float theta;
int ejes;
float sX, sY;
int opcion;

int main(int argc, char* argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(100, 150);
    glutCreateWindow("Transformaciones");
    inicializa();

    glutDisplayFunc(dibuja);
    glutSpecialFunc(tecladoEspecial);
    glutKeyboardFunc(teclado);


    glutMainLoop();
    return 0;
}

void inicializa() {

    glClearColor(0.0, 0.0, 0.0, 1.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-320, 320.0, -240.0, 240.0);
    
    ejes = 0;
    opcion = 1;
    
	u.x = 0.0;
	u.y = 0.0;
	theta = 0.0;
	sX = 1.0;
	sY = 1.0;
}

void dibuja(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	if (ejes) {
		drawAxes();
	}
	glColor3f(1.0, 1.0, 1.0);
	
    pglTranslatef(u.x, u.y);
    pglRotatef(theta);
    pglScalef(sX, sY);
    
    switch(opcion) {
    	case 1:
    		dibujaEstrella(15.0, 40.0);
    	break;
    	
    	case 2:
    		dibujaFlecha();
    	break;
    	
    	default: 
    	break;
    }
    
    glFlush();
}

void tecladoEspecial (int key, int cx, int cy) {

	switch(key) {
		case GLUT_KEY_RIGHT:
			u.x += 10.0;
		break;

		case GLUT_KEY_LEFT:
			u.x -= 10.0;
		break;

		case GLUT_KEY_UP:
			u.y += 10.0;
		break;

		case GLUT_KEY_DOWN:
			u.y -= 10.0;
		break;
		
		case GLUT_KEY_PAGE_UP:
			theta += 10.0;
		break;
		
		case GLUT_KEY_PAGE_DOWN:
			theta -= 10.0;
		break;
		
		case GLUT_KEY_F1:
			opcion = 1;
		break;
		
		case GLUT_KEY_F2:
			opcion = 2;
		break;
	}

	glutPostRedisplay();
}

void teclado (unsigned char key, int cx, int cy) {
	switch(key) {

		case 27:
			exit(0);
		break;
		
		case 'A':
		case 'a':
			ejes = !(ejes);
		break;
		
		case 'x':
			sX -= 0.1;
		break;
		
		case 'X':
			sX += 0.1;
		break;
			
		case 'y':
			sY -= 0.1;
		break;
		
		case 'Y':
			sY += 0.1;
		break;

	}

	glutPostRedisplay();
}

void dibujaEstrella (float minRadi, float maxRadi) {
	float delta = 2.0 * PI / 10.0, x, y, radius, angle;
	int i;

	angle = PI / 2.0;

	glBegin(GL_LINE_LOOP);
	for (i = 0; i < 10; i++) {
		radius = (i % 2) ? minRadi : maxRadi;
		x = radius * cos(angle);
		y = radius * sin(angle);
		glVertex2f(x, y);
		angle += delta;
	}
	glEnd();

}

void drawAxes() {
	glBegin(GL_LINES);
		glColor3f(1.0, 0.0, 0.0);
		glVertex2f(-320.0, 0.0);
		glVertex2f(320.0, 0.0);
		glColor3f(0.0, 1.0, 0.0);
		glVertex2f(0.0, -240.0);
		glVertex2f(0.0, 240.0);
	glEnd();
}

void pglTranslatef(float dx, float dy) {
	glTranslatef(dx, dy, 0.0);
}

void pglRotatef(float angle) {
	glRotatef(angle, 0.0, 0.0, 1.0);
}

void pglScalef(float sx, float sy) {
	glScalef(sx, sy, 1.0);
}

void dibujaFlecha() {
	glBegin(GL_LINE_LOOP);
		glVertex2f(10.0, 0.0);
		glVertex2f(20.0, 0.0);
		glVertex2f(0.0, 20.0);
		glVertex2f(-20.0, 0.0);
		glVertex2f(-10.0, 0.0);
		glVertex2f(-10.0, -20.0);
		glVertex2f(10.0, -20.0);
	glEnd();
}
